package com.lanchetech.merchant.service.impl;


import com.alibaba.excel.util.CollectionUtils;
import com.lanchetech.common.enums.PlatformTypeEnum;
import com.lanchetech.merchant.service.MarketingService;
import com.lanchetech.bean.request.BasePageReq;
import com.lanchetech.bean.request.PageReq;
import com.lanchetech.bean.response.*;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.*;
import com.lanchetech.common.enums.CouponTypeEnum;
import com.lanchetech.common.enums.DeletedEnum;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.lanchetech.service.DaoService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MarketingServiceImpl implements MarketingService {
    @Autowired
    KillActivityMapper killActivityMapper;

    @Autowired
    KillSkuMapper killSkuMapper;

    @Autowired
    CoinRewardMapper coinRewardMapper;

    @Autowired
    CoinDeductionMapper coinDeductionMapper;

    @Autowired
    FlashSaleActivityMapper flashSaleActivityMapper;

    @Autowired
    FlashSaleSpuMapper flashSaleSpuMapper;

    @Autowired
    FlashSaleSkuMapper flashSaleSkuMapper;

    @Autowired
    SkuMapper skuMapper;

    @Autowired
    DaoService daoService;

    @Autowired
    PackagesMapper packagesMapper;

    @Autowired
    PackageSkuMapper packageSkuMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    CoinSettingMapper coinSettingMapper;

    @Autowired
    RedisTemplate redisTemplate;


    @Override
    public ResultData<BasePageResp<CoinRewardResp>> getCoinRewardPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CoinRewardResp> list = coinRewardMapper.findAllPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }
        Map<Long, Spu> spuMap = daoService.getSpuMap(list.stream().map(CoinRewardResp::getSpuId).collect(Collectors.toList()));
        list.stream().forEach(item -> {
            item.setMainImage(spuMap.get(item.getSpuId()).getMainImage());
            item.setMinPrice(spuMap.get(item.getSpuId()).getMinPrice());
            item.setName(spuMap.get(item.getSpuId()).getName());
        });
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editCoinReward(List<CoinReward> req) {
        for (CoinReward coinReward : req) {
            // 先判断此商品是否已经设置，如果已经设置，就直接编辑
            CoinReward result = coinRewardMapper.findOneBySpuId(coinReward.getSpuId());
            if (result != null) {
                coinReward.setId(result.getId());
            }
            if (coinReward.getId() == null) {
                // 创建
                coinReward.setCreatedAt(new Date());
                coinReward.setUpdatedAt(new Date());
                coinRewardMapper.insert2(coinReward);
            } else {
                // 编辑
                coinReward.setUpdatedAt(new Date());
                coinRewardMapper.updateByPrimaryKeySelective(coinReward);
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp deleteCoinReward(Long id) {
        coinRewardMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<CoinDeductionResp>> getCoinDeductionPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CoinDeductionResp> list = coinDeductionMapper.findAllPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }
        Map<Long, Spu> spuMap = daoService.getSpuMap(list.stream().map(CoinDeductionResp::getSpuId).collect(Collectors.toList()));
        list.stream().forEach(item -> {
            item.setMainImage(spuMap.get(item.getSpuId()).getMainImage());
            item.setMinPrice(spuMap.get(item.getSpuId()).getMinPrice());
            item.setName(spuMap.get(item.getSpuId()).getName());
        });
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp editCoinDeduction(List<CoinDeduction> req) {
        for (CoinDeduction coinDeduction : req) {
            // 先判断此商品是否已经设置，如果已经设置，就直接编辑
            CoinDeduction result = coinDeductionMapper.findOneBySpuId(coinDeduction.getSpuId());
            if (result != null) {
                coinDeduction.setId(result.getId());
            }
            if (coinDeduction.getId() == null) {
                // 创建
                coinDeduction.setCreatedAt(new Date());
                coinDeduction.setUpdatedAt(new Date());
                coinDeductionMapper.insert(coinDeduction);
            } else {
                // 编辑
                coinDeduction.setUpdatedAt(new Date());
                coinDeductionMapper.updateByPrimaryKeySelective(coinDeduction);
            }
        }
        return new BaseResp();
    }

    @Override
    public BaseResp editCoinSetting(CoinSetting coinSetting) {
        if (coinSetting.getId() == null) {
            coinSetting.setCreatedAt(new Date());
            coinSetting.setUpdatedAt(new Date());
            coinSettingMapper.insert2(coinSetting);
        } else {
            coinSetting.setUpdatedAt(new Date());
            coinSettingMapper.updateByPrimaryKey(coinSetting);
        }
        return new BaseResp();
    }

    @Override
    public BaseResp deleteCoinSetting(Long id) {
        coinSettingMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<CoinSetting>> getCoinSettingPage(BasePageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<CoinSetting> list = coinSettingMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp deleteCoinDeduction(Long id) {
        coinDeductionMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }

    @Override
    public BaseResp editPackage(PackageVO req) {
        Packages packages = req.getPackages();
        List<PackageSku> packageSkuList = req.getPackageSkuList();
        Date now = new Date();
        if (req.getPackages().getId() == null) {
            packages.setCreatedAt(now);
            packages.setUpdatedAt(now);
            packages.setDeleted(DeletedEnum.DEFAULT.getStatus());
            packages.setSorts(0);
            packagesMapper.insert2(packages);

            packageSkuList.forEach((item) -> {
                item.setActivityId(packages.getId());
                item.setCreatedAt(now);
            });
            packageSkuMapper.batchInsert2(packageSkuList);
        } else {
            // 修改只能改套餐和商品，不能删除或添加商品
            packages.setSorts(null);
            packages.setUpdatedAt(new Date());
            packagesMapper.updateByPrimaryKeySelective(packages);

            // 只修改价格和固定数量
            List<PackageSku> updatePackageSkuList = new ArrayList<>();
            packageSkuList.stream().forEach(item -> {
                updatePackageSkuList.add(PackageSku.builder()
                        .id(item.getId())
                        .price(item.getPrice())
                        .count(item.getCount())
                        .build());
            });
            packageSkuMapper.updateBatchSelective(updatePackageSkuList);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<PackageResp> getPackageDetail(Long id) {
        return new ResultData<>(daoService.getPackageDetail(id));
    }

    @Override
    public ResultData<BasePageResp<Packages>> getPackagePage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Packages> list = packagesMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp deletePackage(Long id) {
        packagesMapper.updateDeletedById(DeletedEnum.DELETED.getStatus(), id);
        return new BaseResp();
    }

    @Override
    public BaseResp editCoupon(Coupon coupon) {
        if (coupon.getId() == null) {
            coupon.setIssuedQuantity(0);
            coupon.setDeleted(DeletedEnum.DEFAULT.getStatus());
            coupon.setPlatformType(PlatformTypeEnum.MERCHANT.getType());
            coupon.setCreatedAt(new Date());
            coupon.setUpdatedAt(new Date());
            couponMapper.insert2(coupon);
        } else {
            // 模拟线下发优惠券场景。优惠券创建好后，只可以修改可领取数量、领取时间、启用禁用，其他不可以改。禁用或删除，则已领取的该优惠券全场失效
            Coupon updateCoupon = Coupon.builder()
                    .id(coupon.getId())
                    .title(coupon.getTitle())
                    .stock(coupon.getStock())
                    .startTime(coupon.getStartTime())
                    .endTime(coupon.getEndTime())
                    .status(coupon.getStatus())
                    .updatedAt(new Date())
                    .build();
            couponMapper.updateByPrimaryKeySelective(updateCoupon);
        }
        return new BaseResp();
    }

    @Override
    public ResultData<CouponVO> getCouponDetail(Long id) {
        CouponVO couponVO = new CouponVO();
        Coupon coupon = couponMapper.selectByPrimaryKey(id);
        couponVO.setCoupon(coupon);
        if (CouponTypeEnum.SPU.getType().equals(coupon.getType())) {
            Spu spu = spuMapper.selectByPrimaryKey(coupon.getSpuId());
            couponVO.setSpu(spu);
        }
        return new ResultData<>(couponVO);
    }

    @Override
    public ResultData<BasePageResp<Coupon>> getCouponPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Coupon> list = couponMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp deleteCoupon(Long id) {
        couponMapper.updateDeletedAndUpdatedAtById(DeletedEnum.DELETED.getStatus(), new Date(), id);
        return new BaseResp();
    }
}